package com.runa.monitor.platinterface.netservice.equipment;

import com.runa.monitor.comm.dto.*;
import com.runa.monitor.comm.dto.newComm.HotMeterVO;
import com.runa.monitor.platinterface.base.BaseContainer;
import com.runa.monitor.platinterface.backwork.function.TaskFunction;
import com.runa.monitor.platinterface.netservice.connect.commstatus.CommStatus;
import com.runa.monitor.platinterface.netservice.server.ListenerServer;
import com.runa.protocol.enums.DtuModel;
import com.runa.protocol.enums.ModbusType;
import com.runa.rccprotocol.dto.equdata.EquData;
import com.runa.rccprotocol.dto.param.ExtendParam;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

@Slf4j
public class SWPNativeDriver extends NetEqu<String> {

    private ListenerServer listener;

    private static List<Point> points;

    private static List<Integer> ids;

    static {
        ids = Arrays.asList(40001, 40002, 40003, 40005, 40007, 40009, 40011, 40013);
        points = new ArrayList<>();
        //标志
        points.add(new Point(ids.get(0), "16位整型", "AB", 0));
        //仪表类型
        points.add(new Point(ids.get(1), "16位整型", "AB", 0));
        //温度
        points.add(new Point(ids.get(2), "浮点", "DCBA", 0));
        //压力
        points.add(new Point(ids.get(3), "浮点", "DCBA", 0));
        //流量
        points.add(new Point(ids.get(4), "浮点", "DCBA", 0));
        //瞬流
        points.add(new Point(ids.get(5), "浮点", "DCBA", 0));
        //累流1
        points.add(new Point(ids.get(6), "浮点", "DCBA", 0));
        //累流2
        points.add(new Point(ids.get(7), "浮点", "DCBA", 0));
    }

    public SWPNativeDriver(String serial, Integer timeout, ListenerServer listener) {
        super(serial, timeout);
        this.listener = listener;
        PlcService service = new PublicDtuPlcService(-1, -1,
                serial(), null, timeout(), ModbusType.MODBUS_RTU, DtuModel.HongDian7710,  null, listener);
        BaseContainer.putPlcService(service);
    }


    @Override
    public void readNodeEqu(List<Node> nodeList, TaskFunction function, EquData.EquDataType type) {
        switch (type) {
            case METER:
                readHouseMeter(nodeList, function);
                break;
            case VALVE:
                break;
            case PUBLIC_UNIT:
                break;
            case TEMPERATURE_PANEL:
                break;
            default:
        }
    }

    private void readHouseMeter(List<Node> nodes, TaskFunction function) {
        CommStatus status = CommStatus.OK;
        for (Node node : nodes) {
            if (node != null) {
                PlcService plc = new PublicDtuPlcService(node.getIndex(), node.getIndex(),
                        serial(), null, timeout(), ModbusType.MODBUS_RTU, DtuModel.HongDian7710, null, listener);
                try {
                    plc.init(points);
                } catch (Exception e) {
                    log.error("plc service初始化失败 ", e);
                }
                function.setStatus(node);
                if (plc.session().isOnline()) {
                    Map<String, Object> res = plc.query(ids);
                    HotMeterVO meterData = new HotMeterVO();
                    meterData.setIndexNo(node.getIndex());
                    if (CommStatus.OK.getStatus().equals(res.get("status"))) {
                        Map<Integer, String> data = (Map<Integer, String>) res.get("data");
                        meterData.setSupplyTemp(Float.valueOf(data.get(ids.get(2))));
                        meterData.setFlow(Float.valueOf(data.get(ids.get(5))) * 3600);
                        float acc1 = Float.parseFloat(data.get(ids.get(6)));
                        float acc2 = Float.parseFloat(data.get(ids.get(7)));
                        meterData.setAccFlow((acc1 * 100 + acc2));
                        meterData.setPressure(Float.valueOf(data.get(ids.get(3))));
                    } else {
                        meterData.setSuccess(false);
                        meterData.setStatus("FFFF");
                    }
                    function.doApply(status, meterData);
                } else {
                    function.doApply(CommStatus.OffLine, Collections.singletonList(node));
                    break;
                }
            }
        }
    }

    @Override
    public void setNodeEquArchive(List<Archive> archives, TaskFunction function) {

    }

    @Override
    public void clearNodeEquArchive(TaskFunction function) {

    }

    @Override
    public void valveOnOffControl(List<Node> valveSerial, boolean ifLock, Integer opening, TaskFunction function) {

    }

    @Override
    public void readNodeRecord(List<Integer> indexes, TaskFunction function) {

    }

    @Override
    public void sentPublicUnitRecord(List<Node> valveSerial, Integer model, Map param, TaskFunction function) {

    }

    @Override
    public void sentPublicUnitModel(List<Node> valveSerial, boolean model, TaskFunction function) {

    }

    @Override
    public void sentExtendParam(ExtendParam param, TaskFunction function) {

    }

    @Override
    public void readPublicUnitRecord(Node valveSerial, Integer model, TaskFunction function) {

    }

    @Override
    public void readPublicUnitAndMeter(Node valveSerial, Node meterSerial, TaskFunction function) {

    }

    @Override
    public void heartbeatUpdate() {

    }

    @Override
    public boolean heartStop() {
        return false;
    }

}
